package com.yh.lq.robot;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.yh.lq.entity.ImType;
import com.yh.lq.entity.LQStatus;
import com.yh.lq.entity.ToClientReq;
import com.yh.lq.retdata.*;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.web.socket.WebSocketSession;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;

/**
 * 酷Q类
 * 每个机器人对应一个对象
 * 保存 机器人自己的QQ 和 ws的session
 */
@Slf4j
public class LQ {

    @Getter
    @Setter
    private String selfId;

    @Getter
    @Setter
    private String selfName;

    @Getter
    @Setter
    private ImType imType;

    @Getter
    @Setter
    private WebSocketSession botSession;

    private ApiHandler apiHandler;


    @Getter
    @Setter
    private List<Class<? extends LQPlugin>> pluginList;

    public LQ(String selfId, WebSocketSession botSession, ApiHandler apiHandler, List<Class<? extends LQPlugin>> pluginList) {
        this.selfId = selfId;
        this.botSession = botSession;
        this.apiHandler = apiHandler;
        this.pluginList = pluginList;
        this.imType = ImType.QQ;
    }

    public LQ(String selfId, ImType imType, WebSocketSession botSession, ApiHandler apiHandler, List<Class<? extends LQPlugin>> pluginList) {
        this.selfId = selfId;
        this.botSession = botSession;
        this.apiHandler = apiHandler;
        this.pluginList = pluginList;
        this.imType = imType;
    }

    /**
     * 发送私聊消息
     *
     * @param user_id     对方 QQ 号
     * @param message     要发送的内容
     * @param auto_escape 消息内容是否作为纯文本发送（即不解析 CQ 码），只在 message 字段是字符串时有效
     * @return 结果
     */
    /**
     * {
     * "Api": "SendMsg",		/API
     * "Robot": "100000"，		/机器人QQ
     * "QQ": "123456"，		/好友QQ
     * "Type": 1，				/消息类型
     * "Content": "测试消息 "	/消息内容
     * }
     */
    public ApiData<MessageData> sendPrivateMsg(long user_id, String message, boolean auto_escape) {
        ApiEnum action = ApiEnum.SEND_PRIVATE_MSG;

        JSONObject params = new JSONObject();
        params.put("Robot", selfId);
        params.put("QQ", user_id);
        params.put("Type", 1);
        params.put("Content", message);
        ApiData<MessageData> result = apiHandler.sendApiMessage(botSession, action, params).toJavaObject(new TypeReference<ApiData<MessageData>>() {
        });
        return result;
    }

    /**
     * 发送群消息
     *
     * @param group_id    群号
     * @param message     要发送的内容
     * @param auto_escape 消息内容是否作为纯文本发送（即不解析 CQ 码），只在 message 字段是字符串时有效
     * @return 结果
     */
    public ApiData<MessageData> sendGroupMsg(long group_id, String message, boolean auto_escape) {

        ApiEnum action = ApiEnum.SEND_GROUP_MSG;

        JSONObject params = new JSONObject();
        params.put("Robot", selfId);
        params.put("Group", group_id);
        params.put("Type", 2);
        params.put("Content", message);

        ApiData<MessageData> result = apiHandler.sendApiMessage(botSession, action, params).toJavaObject(new TypeReference<ApiData<MessageData>>() {
        });
        return result;
    }

    /**
     * 发送群临时消息
     *
     * @param group_id
     * @param userId
     * @param message
     * @param auto_escape
     * @return 结果
     */
    public ApiData<MessageData> sendGroupTempMsg(long group_id, long userId, String message, boolean auto_escape) {

        ApiEnum action = ApiEnum.SEND_GROUP_MSG;

        JSONObject params = new JSONObject();
        params.put("Api", action.getUrl());
        params.put("Robot", selfId);
        params.put("Group", group_id);
        params.put("QQ", userId);
        params.put("Type", 4);
        params.put("Content", message);

        ApiData<MessageData> result = apiHandler.sendApiMessage(botSession, action, params).toJavaObject(new TypeReference<ApiData<MessageData>>() {
        });
        return result;
    }

    /**
     * 获取好友列表
     *
     * @return 结果
     */
    public ApiListData<FriendData> getFriendList() {
        ApiListData<FriendData> result = new ApiListData<>();
        result.setRetcode(0);
        ApiEnum action = ApiEnum.GET_FRIEND_LIST;
        JSONObject params = new JSONObject();
        params.put("Robot", selfId);
        JSONObject resultJson = apiHandler.sendApiMessage(botSession, action, params);
        if (resultJson == null) {
            result.setRetcode(-1);
            return result;
        }
        JSONArray friendArray = resultJson.getJSONArray("data");
        List<FriendData> friendDataList = friendArray.toJavaList(FriendData.class);
        result.setData(friendDataList);
        return result;
    }

    /**
     * 获取群列表
     *
     * @return 结果
     */
    public ApiListData<GroupData> getGroupList() {
        ApiListData<GroupData> result = new ApiListData<>();
        result.setRetcode(0);
        ApiEnum action = ApiEnum.GET_GROUP_LIST;
        JSONObject params = new JSONObject();
        params.put("Robot", selfId);
        JSONObject resultJson = apiHandler.sendApiMessage(botSession, action, params);
        if (resultJson == null) {
            result.setRetcode(-1);
            return result;
        }
        JSONArray jsonArray = resultJson.getJSONArray("data");
        List<GroupData> groupList = jsonArray.toJavaList(GroupData.class);
        result.setData(groupList);
        return result;
    }

    /**
     * 查看是否好友
     *
     * @param user_id QQ 号
     * @return 结果
     */
    @Deprecated
    public ApiData<Boolean> getIsFriend(long user_id) {

        ApiData<Boolean> result = new ApiData<>();
        ApiEnum action = ApiEnum.GET_IS_FRIEND;

        JSONObject params = new JSONObject();
        params.put("Robot", selfId);
        params.put("QQ", user_id);
        JSONObject jsonObject = apiHandler.sendApiMessage(botSession, action, params);
        Boolean isFriend = jsonObject.getBoolean("ReturnLogic");
        result.setData(isFriend);
        result.setRetcode(0);
        return result;
    }


    /**
     * 获取群成员列表
     * <p>
     * 响应内容为 JSON 数组，每个元素的内容和上面的 /get_group_member_info 接口相同，但对于同一个群组的同一个成员，获取列表时和获取单独的成员信息时，某些字段可能有所不同，例如 area、title 等字段在获取列表时无法获得，具体应以单独的成员信息为准。
     *
     * @param group_id 群号
     * @return 结果
     */
    @Deprecated
    public ApiListData<GroupMemberInfoData> getGroupMemberList(long group_id) {
        ApiListData<GroupMemberInfoData> result = new ApiListData<>();
        result.setRetcode(-1);
        ApiEnum action = ApiEnum.GET_GROUP_MEMBER_LIST;
        JSONObject params = new JSONObject();
        params.put("Robot", selfId);
        params.put("Group", group_id);
        JSONObject jsonObject = apiHandler.sendApiMessage(botSession, action, params);
        String returnText = jsonObject.getString("ReturnText");
        if (StringUtils.isEmpty(returnText)) {
            return result;
        }
        JSONObject members = JSON.parseObject(returnText).getJSONObject("members");
        LinkedHashMap<Long, JSONObject> map = members.toJavaObject(new TypeReference<LinkedHashMap<Long, JSONObject>>() {
        });

        List<GroupMemberInfoData> groupMemberList = new ArrayList<>();
        map.forEach((k, v) -> {
            GroupMemberInfoData m = new GroupMemberInfoData();
            m.setUserId(k);
            m.setGroupId(group_id);
            m.setNickname(v.getString("nk"));
            groupMemberList.add(m);
        });
        result.setRetcode(0);
        result.setData(groupMemberList);
        return result;
    }


    /**
     * 获取插件运行状态
     *
     * @return 结果
     */
    @Deprecated
    public ApiData<LQStatus> getStatus() {
        ApiData<LQStatus> result = new ApiData<>();
        result.setRetcode(-1);
        ApiEnum action = ApiEnum.GET_STATUS;
        JSONObject params = new JSONObject();
        params.put("Robot", selfId);
        JSONObject resultJson = apiHandler.sendApiMessage(botSession, action, params);
        if (resultJson == null) {
            log.info("获取消息为空？");
            return result;
        }
        String returnText = resultJson.getString("ReturnText");
        if (StringUtils.isEmpty(returnText)) {
            return result;
        }
        String[] split = returnText.split("\\|");
        LQStatus lqStatus = new LQStatus();
        lqStatus.setSelfId(Long.valueOf(split[1]));
        lqStatus.setNickName(split[0]);
        lqStatus.setState(split[2]);
        lqStatus.setRate(split[3]);
        lqStatus.setReceiveNum(Long.valueOf(split[4]));
        lqStatus.setSendNum(Long.valueOf(split[5]));
        lqStatus.setOnlineTime(split[6]);
        result.setRetcode(0);
        result.setData(lqStatus);
        return result;
    }

    @Deprecated
    public ApiData<String> getGroupName(long groupId) {
        ApiData<String> result = new ApiData<>();
        result.setRetcode(-1);
        ApiEnum action = ApiEnum.GET_GROUP_NAME;
        JSONObject params = new JSONObject();
        params.put("Robot", selfId);
        params.put("Group", groupId);
        JSONObject resultJson = apiHandler.sendApiMessage(botSession, action, params);
        String returnText = resultJson.getString("ReturnText");
        result.setRetcode(0);
        result.setData(returnText);
        return result;
    }

    public ApiData<String> getUserNickName(long userId) {
        ApiData<String> result = new ApiData<>();
        result.setRetcode(-1);
        ApiEnum action = ApiEnum.GET_USER_NICK_NAME;
        JSONObject params = new JSONObject();
        params.put("Robot", selfId);
        params.put("QQ", userId);
        JSONObject resultJson = apiHandler.sendApiMessage(botSession, action, params);
        if (resultJson == null) {
            return result;
        }
        String returnText = resultJson.getString("data");
        result.setRetcode(0);
        result.setData(returnText);
        return result;
    }

    //以下为微信接口方法

    /**
     * 发送微信私聊消息
     *
     * @param user_id
     * @param message
     * @param auto_escape
     * @return
     */
    public ApiData<String> sendWeChatPrivateMsg(String user_id, String message, boolean auto_escape) {
        ApiEnum action = ApiEnum.WECHAT_SEND_PRIVATE_MSG;
        ToClientReq req = ToClientReq.builder()
                .imType(ImType.WE_CHAT.getIndex())
                .weChatRobot(selfId)
                .weChatUserId(user_id)
                .content(message)
                .build();
        JSONObject params = JSONObject.parseObject(JSON.toJSONString(req));
        ApiData<String> result = apiHandler.sendApiMessage(botSession, action, params).toJavaObject(new TypeReference<ApiData<String>>() {
        });
        return result;
    }

    /**
     * 发送微信群消息并at
     *
     * @param groupId
     * @param userId      要at的某人的id
     * @param userName    要at的某人的昵称
     * @param message
     * @param auto_escape
     * @return
     */
    public ApiData<String> sendWeChatPublicAtMsg(String groupId, String userId, String userName, String message, boolean auto_escape) {
        ApiEnum action = ApiEnum.WECHAT_SEND_PUBLIC_AT_MSG;
        ToClientReq req = ToClientReq.builder()
                .imType(ImType.WE_CHAT.getIndex())
                .weChatRobot(selfId)
                .weChatGroupId(groupId)
                .weChatUserId(userId)
                .weChatUserName(userName)
                .content(message)
                .build();
        JSONObject params = JSONObject.parseObject(JSON.toJSONString(req));
        ApiData<String> result = apiHandler.sendApiMessage(botSession, action, params).toJavaObject(new TypeReference<ApiData<String>>() {
        });
        return result;
    }

    /**
     * 发送朴实无华的微信群消息
     *
     * @param groupId
     * @param message
     * @param auto_escape
     * @return
     */
    public ApiData<String> sendWeChatPublicMsg(String groupId, String message, boolean auto_escape) {
        ApiEnum action = ApiEnum.WECHAT_SEND_PUBLIC_MSG;
        ToClientReq req = ToClientReq.builder()
                .imType(ImType.WE_CHAT.getIndex())
                .weChatRobot(selfId)
                .weChatGroupId(groupId)
                .content(message)
                .build();
        JSONObject params = JSONObject.parseObject(JSON.toJSONString(req));
        ApiData<String> result = apiHandler.sendApiMessage(botSession, action, params).toJavaObject(new TypeReference<ApiData<String>>() {
        });
        return result;
    }

    /**
     * 获取微信好友列表
     *
     * @param auto_escape
     * @return
     */
    public ApiListData<FriendData> getWeChatFriendList(boolean auto_escape) {
        ApiEnum action = ApiEnum.WECHAT_GET_FRIEND_LIST;
        ToClientReq req = ToClientReq.builder()
                .imType(ImType.WE_CHAT.getIndex())
                .weChatRobot(selfId)
                .auto_escape(auto_escape)
                .build();
        JSONObject params = JSONObject.parseObject(JSON.toJSONString(req));
        ApiListData<FriendData> result = apiHandler.sendApiMessage(botSession, action, params).toJavaObject(new TypeReference<ApiListData<FriendData>>() {
        });
        return result;
    }

    /**
     * 获取微信群列表
     *
     * @param auto_escape
     * @return
     */
    public ApiListData<GroupData> getWeChatGroupList(boolean auto_escape) {
        ApiEnum action = ApiEnum.WECHAT_GET_GROUP_LIST;
        ToClientReq req = ToClientReq.builder()
                .imType(ImType.WE_CHAT.getIndex())
                .weChatRobot(selfId)
                .auto_escape(auto_escape)
                .build();
        JSONObject params = JSONObject.parseObject(JSON.toJSONString(req));
        ApiListData<GroupData> result = apiHandler.sendApiMessage(botSession, action, params).toJavaObject(new TypeReference<ApiListData<GroupData>>() {
        });
        return result;
    }

    /**
     * 获取机器人名字
     *
     * @return
     */
    public ApiData<String> getWeChatRobotName() {
        ApiEnum action = ApiEnum.WECHAT_GET_ROBOT_NAME;
        ToClientReq req = ToClientReq.builder()
                .imType(ImType.WE_CHAT.getIndex())
                .weChatRobot(selfId)
                .build();
        JSONObject params = JSONObject.parseObject(JSON.toJSONString(req));
        ApiData<String> result = apiHandler.sendApiMessage(botSession, action, params).toJavaObject(new TypeReference<ApiData<String>>() {
        });
        return result;
    }

    /**
     * 获取微信机器人头像链接
     * 注意：暂时未调通，返回的是空字符串。。。
     * @return
     */
    @Deprecated
    public ApiData<String> getWeChatRobotHeadImgUrl() {
        ApiEnum action = ApiEnum.WECHAT_GET_ROBOT_HEAD_IMAGE;
        ToClientReq req = ToClientReq.builder()
                .imType(ImType.WE_CHAT.getIndex())
                .weChatRobot(selfId)
                .build();
        JSONObject params = JSONObject.parseObject(JSON.toJSONString(req));
        ApiData<String> result = apiHandler.sendApiMessage(botSession, action, params).toJavaObject(new TypeReference<ApiData<String>>() {
        });
        return result;
    }


}
